package org.ielts.action;

import static com.yifeng.struts2.ResultParameters.*;
import static com.yifeng.struts2.ResultConstants.*;
import static com.yifeng.struts2.ActionUtils.*;

import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.http.client.utils.URIBuilder;
import org.ielts.domain.Sex;
import org.ielts.domain.base.Course;
import org.ielts.domain.base.Lesson;
import org.ielts.domain.base.SignCourse;
import org.ielts.domain.base.Student;
import org.ielts.domain.log.ConsultLog;
import org.ielts.domain.log.FirstRecordLog;
import org.ielts.domain.log.OrderLessonLog;
import org.ielts.domain.query.OrderLessonQuery;
import org.ielts.domain.query.VisitorQuery;
import org.ielts.domain.report.LessonWithListenerCount;
import org.ielts.domain.security.User;
import org.ielts.repository.FirstRecordLogRepository;
import org.ielts.service.ConsultantService;
import org.ielts.service.CourseService;
import org.ielts.service.FirstRecordLogService;
import org.ielts.service.FrontService;
import org.ielts.service.LessonService;
import org.ielts.service.StudentService;
import org.ielts.service.security.UserService;
import org.ielts.util.MapListWapper;
import org.ielts.util.SimpleCellReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.ielts.profile.IeltsProfile;
import com.yifeng.ProfileContext;
import com.yifeng.TimePair;
import com.yifeng.dto.DtoTable;
import com.yifeng.dto.IDtoRow;
import com.yifeng.dto.UploadFile;
import com.yifeng.modules.annotations.Operation;
import com.yifeng.poi.ExcelUtils;
import com.yifeng.profile.Profile;
import com.yifeng.sequence.ISeqService;
import com.yifeng.struts2.RequestParameters;
import com.yifeng.utils.JsonResultBuilder;
import com.yifeng.utils.PageUtils;
import com.yifeng.web.Pagers;
import com.yifeng.web.Paginations;

public class FrontAction extends BaseAction {

	@Operation(result = FILL)
	public String subscribeLesson() {
		Date now = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.set(2013, 4, 25, 0, 0);
		now = calendar.getTime();

		String single = form.readString("single");
		boolean singleSel = true;
		if (StringUtils.isBlank(single)) {
			singleSel = false;
		}
		put("singleSel", singleSel);

		String name = form.readString("name");

		String[] selectedLessons = form.readStrings("selectedLesson");
		String selectedSign = form.readString("selectedSign");

		put("selectedLessons", selectedLessons);
		put("selectedSign", selectedSign);

		Date startDate = valueReader.name("selectedDay").defaultValue(now).dateValue("yyyy-MM-dd");
		startDate = DateUtils.truncate(startDate, Calendar.DATE);
		Date endDate = DateUtils.addDays(startDate, 1);
		Iterable<LessonWithListenerCount> lessons = lessonService.findReportBetweenDate(startDate, endDate);

		put("lessons", lessons);

		Iterable<Student> students = new ArrayList<Student>();

		if (StringUtils.isNotBlank(name)) {
			name = name.trim();
			char c = name.charAt(0);

			if (c >= '0' && c <= '9') {
				students = studentService.findByStuId(name);
			} else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
				name = name.toLowerCase();
				students = studentService.findByPinyin(name);
			} else {
				students = studentService.findByName(name);
			}
		}
		put("students", students);

		return FILL;
	}

	@Operation(result = FILL)
	public String orderLesson() {
		return FILL;
	}

	@Operation(result = JSON)
	public String doOrderLesson() {
		String signCourseId = form.readString("signCourseId");
		String[] lessonIds = form.readString("lessonIds").split(",");

		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "roles", "courses", "consultStatus", "teachings", "courseType",
				"orderLessonLogs", "signCourseLogs", "schoolLogs", "orders" });
		jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

		Collection<OrderLessonLog> logs = frontService.findOrderLessonLog(signCourseId, lessonIds);
		if (logs.size() > 0) {
			StringBuilder sb = new StringBuilder();
			for (OrderLessonLog orderLessonLog : logs) {
				String lessonName = orderLessonLog.getLesson().getName();
				sb.append(lessonName);
				sb.append(",");
			}

			JSONArray logsJson = JSONArray.fromObject(logs, jsonConfig);
			setJson(JsonResultBuilder.success(false).msg("订课失败，该学员已订过课程：" + sb + "请去除掉已订的课程后再次订课。")
					.add("logs", logsJson).json());

			return JSON;
		}

		logs = frontService.orderLesson(signCourseId, lessonIds);

		JSONArray logsJson = JSONArray.fromObject(logs, jsonConfig);

		setJson(JsonResultBuilder.success(true).msg("订课成功").add("logs", logsJson).json());

		return JSON;
	}

	@Autowired
	FirstRecordLogService firstRecordLogService;

	@Operation(result = FILL)
	public String reportVisitor() {
		Iterable<User> users = frontService.findFrontUser();
		put("users", users);

		VisitorQuery query = new VisitorQuery();

		Date beginTime = valueReader.name("startDate").defaultValue(null).dateValue("yyyy-MM-dd");
		Date endTime = valueReader.name("endDate").defaultValue(null).dateValue("yyyy-MM-dd");

		if (beginTime != null && endTime != null) {
			endTime = DateUtils.addDays(endTime, 1);

			TimePair timePair = new TimePair();
			timePair.setStartDate(beginTime);
			timePair.setEndDate(endTime);

			query.setTimePair(timePair);
		}

		String creatorId = form.readString("creator");
		if (StringUtils.isNotBlank(creatorId)) {
			query.setCreator(creatorId);
		}

		String campus = form.readString("campus");
		if (StringUtils.isNotBlank(campus)) {
			String campusId = ((IeltsProfile) Profile.getInstance().getProfile()).getCampus();
			if (campusId != null) {
				query.setCampusId(campusId);
			}
		}

		String name = form.readString("name");
		if (StringUtils.isNotBlank(name)) {
			query.setName(name);
		}

		String number = form.readString("number");
		if (StringUtils.isNotBlank(number)) {
			query.setNumber(number);
		}

		Pageable pageable = getPageable();

		Page<FirstRecordLog> firstRecordLogs = firstRecordLogService.findAll(query, pageable);

		put(PAGINATIONS, new Paginations(firstRecordLogs));
		put("firstRecordLogs", firstRecordLogs);

		return FILL;
	}

	@Operation(result = FILL)
	public String orderLesson1() throws URISyntaxException {
		OrderLessonQuery orderLessonQuery = new OrderLessonQuery();

		Date today = DateUtils.truncate(new Date(), Calendar.DATE);

		Date beginTime = valueReader.name("startDate").defaultValue(today).dateValue("yyyy-MM-dd");
		Date endTime = DateUtils.addDays(beginTime, 1);

		orderLessonQuery.setDate(beginTime);

		String[] lessons = form.readStrings("lesson");
		orderLessonQuery.setLessonId(lessons);

		String name = form.readString("name");
		orderLessonQuery.setName(name);

		String signCourse = form.readString("signCourse");
		orderLessonQuery.setSignCourse(signCourse);

		String type = form.readString("type");
		orderLessonQuery.setType(type);

		if (StringUtils.isBlank(form.readString("single"))) {
			orderLessonQuery.setSingle(false);
		} else {
			orderLessonQuery.setSingle(true);
		}

		Iterable<Lesson> selectedLessons = lessonService.findReportByIds(orderLessonQuery.getLessonId());
		put("selected", selectedLessons);

		Iterable<LessonWithListenerCount> reports = lessonService.findReportBetweenDate(beginTime, endTime);

		put("currentDate", new SimpleDateFormat("yyyy-MM-dd").format(beginTime));
		put("reports", reports);
		put("orderLessonQuery", orderLessonQuery);

		String baseUrl = buildBaseUrl(orderLessonQuery);
		put("baseUrl", baseUrl);

		String noSingleBaseUrl = buildNoSingleBaseUrl(orderLessonQuery);
		put("noSingleBaseUrl", noSingleBaseUrl);

		put("startDate", new SimpleDateFormat("yyyy-MM-dd").format(orderLessonQuery.getDate()));

		return FILL;
	}

	public String createClearUrl(OrderLessonQuery orderLessonQuery) throws URISyntaxException {
		OrderLessonQuery newQuery = orderLessonQuery.copy();

		String[] lessons = new String[0];
		newQuery.setLessonId(lessons);

		String url = buildUrl(newQuery);

		return url;
	}

	public String createRemoveUrl(Lesson lesson, OrderLessonQuery orderLessonQuery) throws URISyntaxException {
		OrderLessonQuery newQuery = orderLessonQuery.copy();

		Set<String> list = new HashSet<String>(Arrays.asList(newQuery.getLessonId()));
		list.remove(lesson.getId());

		String[] lessons = new String[list.size()];
		lessons = list.toArray(lessons);
		newQuery.setLessonId(lessons);

		String url = buildUrl(newQuery);

		return url;
	}

	public String createUrl(Lesson lesson, OrderLessonQuery orderLessonQuery) throws URISyntaxException {
		OrderLessonQuery newQuery = orderLessonQuery.copy();

		boolean single = newQuery.isSingle();

		if (single) {
			String[] lessonId = new String[] { lesson.getId() };
			newQuery.setLessonId(lessonId);
		} else {
			Set<String> list = new HashSet<String>(Arrays.asList(newQuery.getLessonId()));
			list.add(lesson.getId());
			String[] lessons = new String[list.size()];
			lessons = list.toArray(lessons);
			newQuery.setLessonId(lessons);
		}

		String url = buildUrl(newQuery);

		return url;
	}

	public String buildNoSingleBaseUrl(OrderLessonQuery orderLessonQuery) throws URISyntaxException {
		URIBuilder uriBuilder = new URIBuilder("?");

		uriBuilder.addParameter("startDate", new SimpleDateFormat("yyyy-MM-dd").format(orderLessonQuery.getDate()));
		for (String lessonId : orderLessonQuery.getLessonId()) {
			uriBuilder.addParameter("lesson", lessonId);
		}
		uriBuilder.addParameter("name", orderLessonQuery.getName());
		uriBuilder.addParameter("signCourse", orderLessonQuery.getSignCourse());
		uriBuilder.addParameter("type", orderLessonQuery.getType());

		String url = uriBuilder.build().toString();
		return url;
	}

	private String buildBaseUrl(OrderLessonQuery orderLessonQuery) throws URISyntaxException {
		URIBuilder uriBuilder = new URIBuilder("?");

		for (String lessonId : orderLessonQuery.getLessonId()) {
			uriBuilder.addParameter("lesson", lessonId);
		}
		uriBuilder.addParameter("name", orderLessonQuery.getName());
		uriBuilder.addParameter("signCourse", orderLessonQuery.getSignCourse());
		uriBuilder.addParameter("type", orderLessonQuery.getType());
		if (orderLessonQuery.isSingle()) {
			uriBuilder.addParameter("single", "single");
		}

		String url = uriBuilder.build().toString();
		return url;
	}

	private String buildUrl(OrderLessonQuery orderLessonQuery) throws URISyntaxException {
		URIBuilder uriBuilder = new URIBuilder("?");

		uriBuilder.addParameter("startDate", new SimpleDateFormat("yyyy-MM-dd").format(orderLessonQuery.getDate()));
		for (String lessonId : orderLessonQuery.getLessonId()) {
			uriBuilder.addParameter("lesson", lessonId);
		}
		uriBuilder.addParameter("name", orderLessonQuery.getName());
		uriBuilder.addParameter("signCourse", orderLessonQuery.getSignCourse());
		uriBuilder.addParameter("type", orderLessonQuery.getType());
		if (orderLessonQuery.isSingle()) {
			uriBuilder.addParameter("single", "single");
		}

		String url = uriBuilder.build().toString();
		return url;
	}

	@Autowired
	LessonService lessonService;

	@Operation(result = FILL)
	public String checkLesson() {
		Date today = DateUtils.truncate(new Date(), Calendar.DATE);

		Date beginTime = valueReader.name("startDate").defaultValue(today).dateValue("yyyy-MM-dd");
		Date endTime = DateUtils.addDays(beginTime, 1);

		Iterable<LessonWithListenerCount> reports = lessonService.findReportBetweenDate(beginTime, endTime);

		Date preTime = DateUtils.addDays(beginTime, -1);

		put("preDate", new SimpleDateFormat("yyyy-MM-dd").format(preTime));
		put("currentDate", new SimpleDateFormat("yyyy-MM-dd").format(beginTime));
		put("nextDate", new SimpleDateFormat("yyyy-MM-dd").format(endTime));
		put("reports", reports);

		return FILL;
	}

	@Autowired
	UserService userService;

	@Autowired
	ConsultantService consultantService;

	@Autowired
	CourseService courseService;

	@Operation(result = FILL)
	public String firstVisit() {

		String no = nextNo();
		put("no", no);

		Iterable<User> users = consultantService.listConsultant();
		put("users", users);

		Iterable<User> fronts = frontService.listFront();
		put("fronts", fronts);

		Iterable<Course> courses = courseService.findAll();
		put("courses", courses);

		return FILL;
	}

	@Operation(result = JSON)
	public String doFirstVisit() {
		String no = form.readString("no");
		String name = form.readString("name");

		int age = valueReader.name("age").defaultValue(0).intValue();
		Date birthday = null;
		if (age != 0) {
			birthday = DateUtils.addYears(new Date(), -age);
		}

		String job = form.readString("job");
		String address = form.readString("address");
		String phone = form.readString("phone");
		String zip = form.readString("zip");
		String mobile = form.readString("mobile");
		String education = form.readString("education");
		String stuTitle = form.readString("stu-title");
		String email = form.readString("email");

		Sex sex = Sex.NotSet;
		String s = form.readString("sex");
		if (StringUtils.isNotBlank(s)) {
			sex = Sex.valueOf(s);
		}

		Student student = new Student();
		student.setAddress(address);
		student.setBirthday(birthday);
		student.setConsultStarred(true);
		student.setEducation(education);
		student.setJob(job);
		student.setMobile(mobile);
		student.setName(name);
		student.setNo(no);
		student.setPhone(phone);
		student.setSex(sex);
		student.setZip(zip);
		student.setTitle(stuTitle);
		student.setEmail(email);

		String source = form.readString("source");
		String visitTitle = form.readString("visit-title");
		String front = form.readString("front");
		// 记录学员，并记录初次访问日志
		FirstRecordLog firstRecordLog = frontService.firstVisit(student, source, visitTitle, front);

		String consultId = form.readString("consultId");
		String title = form.readString("title");
		// 记录分配咨询师
		frontService.appointConsultor(firstRecordLog.getStudent().getId(), consultId, title);

		// 记录咨询记录
		String courseId = form.readString("courseId");
		frontService.consult(student.getId(), courseId);

		student = firstRecordLog.getStudent();

		setJson(JsonResultBuilder.success(true).msg("提交成功").add("student", student).json());

		return JSON;
	}

	@Autowired
	FrontService frontService;

	@Autowired
	StudentService studentService;

	@Operation(result = JSON)
	public String doAppointConsultor() {
		String studentId = form.readString("studentId");
		String title = form.readString("title");
		String consultId = form.readString("consultId");

		frontService.appointConsultor(studentId, consultId, title);
		setJson(JsonResultBuilder.success(true).msg("变更咨询师成功").json());

		return JSON;
	}

	@Operation(result = JSON)
	public String doAppointTutor() {
		String studentId = form.readString("studentId");
		String title = form.readString("title");
		String tutorId = form.readString("tutorId");

		frontService.appointTutor(studentId, tutorId, title);
		setJson(JsonResultBuilder.success(true).msg("变更指导员成功").json());

		return JSON;
	}

	@Autowired
	ISeqService seqService;

	// 20表示校区
	String local = "20";

	public String nextNo() {
		String day = new SimpleDateFormat("yyyyMMdd").format(new Date());
		long no = seqService.next("student.no" + day);

		String strNo = String.format("%04d", no);

		return local + day + strNo;
	}

	@Operation(result = FILL)
	public String importExcel() {
		form = RequestParameters.getForm();
		UploadFile uploadFile = form.readFile("excel");

		Calendar calendar = Calendar.getInstance();

		int year = calendar.get(Calendar.YEAR);
		String campus = "4028c2cb3ea79d77013ea79d85cc000a";

		if (uploadFile != null) {

			MapListWapper<String, User> ccsm = userService.findNameIdMapMatchRoleName("课程顾问");
			MapListWapper<String, User> tutorsm = userService.findNameIdMapMatchRoleName("学习顾问");

			MapListWapper<String, Course> coursesm = courseService.findNameIdMap();

			put("ccs", ccsm.getList());
			put("tutors", tutorsm.getList());

			put("courses", coursesm.getList());

			List<SignCourse> cs = new ArrayList<SignCourse>();

			DtoTable dtoTable = ExcelUtils.book(uploadFile.getFile()).sheet(0)
					.addColumn(1, "date", new SimpleCellReader(false))
					.addColumn(2, "time", new SimpleCellReader(false)).addColumn(3, "name")
					.addColumn(4, "sex", new SimpleCellReader()).addColumn(5, "age", new SimpleCellReader())
					.addColumn(6, "phone", new SimpleCellReader()).addColumn(7, "front").addColumn(8, "cc")
					.addColumn(9, "type").addColumn(10, "source").addColumn(11, "note")
					.addColumn(12, "tmkOwner", new SimpleCellReader()).parseToTable(1);
			List<IDtoRow> rows = new ArrayList<IDtoRow>();
			for (IDtoRow row : dtoTable) {
				if (row.get("date") != null) {
					Object ageObj = row.get("age");
					Object sexObj = row.get("sex");
					if (sexObj != null && sexObj instanceof Number && ageObj != null && ageObj instanceof String) {
						String sex = (String) row.get("age");
						row.put("age", row.get("sex"));
						row.put("sex", sex);
					}
					rows.add(row);
				}
			}
			put("rows", rows);
		}
		return FILL;
	}
}
